/**
 *  fileName:原型和原型链
 *  time:2022/3/17
 *  todo:$END$
 */


// todo:只有函数(非箭头)有原型 prototype
const obj = {
  a: 2
}
const fn = () => {
}
const fn2 = function () {
}

function fn3 () {
}

const fn4 = new Function()

console.log(`obj.prototype ==> `, obj.prototype)
console.log(`fn.prototype ==> `, fn.prototype)
console.log(`fn2.prototype ==> `, fn2.prototype)
console.log(`fn3.prototype ==> `, fn3.prototype)
console.log(`fn4.prototype ==> `, fn4.prototype)

// todo:函数的原型的constructor(构造函数)指向函数本身
console.log(`fn2.prototype.constructor === fn2 ==> `, fn2.prototype.constructor === fn2)

// todo:constructor 构造函数
console.log(`obj.constructor ==> `, obj.constructor)
console.log(`typeof obj.constructor ==> `, typeof obj.constructor)

console.log(`fn2.constructor ==> `, fn2.constructor)
console.log(`typeof fn2.constructor ==> `, typeof fn2.constructor)

console.log(`fn2.constructor.prototype ==> `, fn2.constructor.prototype)
console.log(`typeof fn2.constructor.prototype ==> `, typeof fn2.constructor.prototype)

console.log(`obj.constructor.prototype ==> `, obj.constructor.prototype)
console.log(`typeof obj.constructor.prototype ==> `, typeof obj.constructor.prototype)
console.log(`obj.constructor.prototype.prototype ==> `, obj.constructor.prototype.prototype)

console.log(`fn2.prototype.prototype ==> `, fn2.prototype.prototype)

// todo:预定义属性__proto__ === constructor.prototype
console.log(`obj.__proto__ ==> `, obj.__proto__)
console.log(`obj.__proto__ === obj.constructor.prototype ==> `, obj.__proto__ === obj.constructor.prototype)

console.log(`fn.__proto__ ==> `, fn.__proto__)
console.log(`fn2.__proto__ ==> `, fn2.__proto__)
console.log(`fn.__proto__ === fn.constructor.prototype ==> `, fn.__proto__ === fn.constructor.prototype)
console.log(`fn2.__proto__ === fn2.constructor.prototype ==> `, fn2.__proto__ === fn2.constructor.prototype)

console.log(`fn2.constructor.constructor ==> `, fn2.constructor.constructor)
console.log(`fn2.constructor.constructor.constructor ==> `, fn2.constructor.constructor.constructor)
console.log(`fn2.constructor === fn2.constructor.constructor ==> `, fn2.constructor === fn2.constructor.constructor)
console.log(`fn2.constructor.constructor === fn2.constructor.constructor.constructor ==> `, fn2.constructor.constructor === fn2.constructor.constructor.constructor)

console.log(`obj.constructor.constructor ==> `, obj.constructor.constructor)
console.log(`obj.constructor.constructor.constructor ==> `, obj.constructor.constructor.constructor)

console.log(`fn2.__proto__.constructor ==> `, fn2.__proto__.constructor)

// todo:构造函数
const Person = function () {
}
Person.prototype = {
  age: 18
}
const person = new Person()
console.log(`person.age ==> `, person.age)
console.log(`person.constructor ==> `, person.constructor)

console.log(`fn2.__proto__.constructor ==> `, fn2.__proto__.constructor)
console.log(`fn2.__proto__.constructor.prototype ==> `, fn2.__proto__.constructor.prototype)
console.log(`fn2.__proto__.__proto__ ==> `, fn2.__proto__.__proto__)
console.log(`fn2.__proto__ === fn2.__proto__.__proto__ ==> `, fn2.__proto__ === fn2.__proto__.__proto__)
console.log(`fn2.__proto__.__proto__ === obj.__proto__ ==> `, fn2.__proto__.__proto__ === obj.__proto__)
console.log(`fn2.__proto__.__proto__ === person.__proto__ ==> `, fn2.__proto__.__proto__ === person.__proto__)

console.log(`person.__proto__ ==> `, person.__proto__)
console.log(`fn2.prototype.__proto__ ==> `, fn2.prototype.__proto__)
console.log(`fn2.prototype.__proto__ === obj.__proto__ ==> `, fn2.prototype.__proto__ === obj.__proto__)

console.log(`obj.__proto__.__proto__ ==> `, obj.__proto__.__proto__)
console.log(`obj.__proto__.constructor ==> `, obj.__proto__.constructor)
console.log(`person.prototype ==> `, person.prototype)

console.log(`fn2.__proto__.prototype ==> `, fn2.__proto__.prototype)
console.log(`fn2.prototype ==> `, fn2.prototype)
console.log(`fn2.prototype === obj.__proto__ ==> `, fn2.prototype === obj.__proto__)

console.log(`fn2.__proto__.toString() ==> `, fn2.__proto__.toString())


console.log(`typeof fn ==> `, typeof fn)
console.log(`fn.__proto__ ==> `, fn.__proto__)
